package cc.rengu.igas.bsps.core.service.trans;

import cc.rengu.igas.bsps.common.constant.BspsAppParamConstant;
import cc.rengu.igas.bsps.common.dao.*;
import cc.rengu.igas.bsps.common.dao.impl.*;
import cc.rengu.igas.bsps.common.entity.*;
import cc.rengu.igas.bsps.common.enums.*;
import cc.rengu.igas.bsps.core.model.UserSessionInfo;
import cc.rengu.igas.bsps.core.service.base.ManageService;
import cc.rengu.igas.bsps.facade.base.Header;
import cc.rengu.igas.bsps.facade.bean.MchntBindInfoBean;
import cc.rengu.igas.bsps.facade.bean.PrivilegeInfoBean;
import cc.rengu.igas.bsps.facade.request.MchntBindRegisterRequest;
import cc.rengu.igas.bsps.facade.response.MchntBindRegisterResponse;
import cc.rengu.igas.channel.wechat.facade.request.MchntAuthMsgPushRequest;
import cc.rengu.igas.share.common.util.SensitiveDataUtil;
import cc.rengu.igas.share.core.model.GroupMchntInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.common.enums.PinTypeEnum;
import cc.rengu.oltp.service.common.enums.SmsTypeEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.PasswordInfo;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.SafeKeyBoardService;
import cc.rengu.oltp.service.realize.SmsService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.SafeKeyBoardServiceImpl;
import cc.rengu.oltp.service.realize.impl.SmsServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 商户绑定注册.
 *
 * @author zhangxuran (联调修改)
 * @version 1.0
 * @date 2020.07.14
 */
public class MchntBindRegisterService extends ManageService {


    @Override
    protected Object bizBeforeCust() throws Exception {
        MchntBindRegisterRequest mchntBindRegisterRequest = new MchntBindRegisterRequest();
        ConvertUtil.convertOutput(mchntBindRegisterRequest);
        return mchntBindRegisterRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        MchntBindRegisterResponse mchntBindRegisterResponse = new MchntBindRegisterResponse();
        MchntBindRegisterRequest mchntBindRegisterRequest = (MchntBindRegisterRequest) request;
        String instId = mchntBindRegisterRequest.getHeader().getInstId();
        String authId = mchntBindRegisterRequest.getSmsAuthId();
        String smsCode = mchntBindRegisterRequest.getSmsCode();
        String mchntNo = mchntBindRegisterRequest.getMchntNo();
        String mchntType = mchntBindRegisterRequest.getMchntType();
        String userLoginId = mchntBindRegisterRequest.getUserId();
        String password = mchntBindRegisterRequest.getPassword();
        String confirmPassword = mchntBindRegisterRequest.getConfirmPassword();
        String openId = mchntBindRegisterRequest.getOpenId();
        String chanlId = mchntBindRegisterRequest.getHeader().getChanlId();
        rglog.info("公共必填性校验");
        if (StringUtil.isEmptyOrNull(instId) || StringUtil.isEmptyOrNull(mchntNo) || StringUtil.isEmptyOrNull(mchntType) || StringUtil.isEmptyOrNull(authId) || StringUtil.isEmptyOrNull(smsCode)) {
            rglog.error("必填性校验失败！", instId, mchntNo, mchntType, authId, smsCode);
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }

        //当微信端 openId不能为空
        if ("WECHAT".equals(chanlId)) {
            rglog.info("微信端必填校验");
            if (StringUtil.isEmptyOrNull(mchntBindRegisterRequest.getOpenId())) {
                rglog.error("必填性校验失败！instId:<{}>,mchntNo:<{}>,mchntType:<{}>,authId:<{}>,smsCode:<{}>", instId, mchntNo, mchntType, authId, smsCode);
                throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
            }
            rglog.info("校验当前微信号是否已注册用户（商户或拓展经理）");
            BspsUserInfoMapper bspsUserInfoMapper = new BspsUserInfoMapperImpl();
            UserInfo userInfo = bspsUserInfoMapper.selectBspsUserInfoByOpenId(instId, openId);
            if (null != userInfo) {
                rglog.error("微信号是否已绑定商户校验！instId:<{}>,openId:<{}>", instId, openId);
                throw new BizException(RespCodeEnum.USER_ALREADY_BIND_MCHNT.getRespCode(), RespCodeEnum.USER_ALREADY_BIND_MCHNT.getRespDesc());
            }
        } else if ("PCWEB".equals(chanlId)) {
            rglog.info("PC端必填校验");
            if (StringUtil.isEmptyOrNull(userLoginId) || StringUtil.isEmptyOrNull(password) || StringUtil.isEmptyOrNull(confirmPassword) || !StringUtil.isEmptyOrNull(mchntBindRegisterRequest.getOpenId())) {
                rglog.error("必填性校验失败！instId:<{}>,mchntNo:<{}>,mchntType:<{}>,authId:<{}>,smsCode:<{}>", instId, mchntNo, mchntType, authId, smsCode);
                throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
            }
        }

        if (!StringUtil.isEmptyOrNull(userLoginId) && !StringUtil.isEmptyOrNull(password) && !StringUtil.isEmptyOrNull(confirmPassword)) {
            rglog.info("防重名校验，校验登录账号");
            UserInfoMapper userInfoMapper = new UserInfoMapperImpl();
            List<UserInfo> userInfoList = userInfoMapper.selectBspsUserInfoByUserLoginId(instId, userLoginId);
            if (!CollectionUtils.isEmpty(userInfoList)) {
                rglog.error("账户已存在，请修改后重新注册", instId, mchntNo, mchntType, authId, smsCode);
                throw new BizException(RespCodeEnum.USER_ALREADY_REGISTER.getRespCode(), RespCodeEnum.USER_ALREADY_REGISTER.getRespDesc());
            }
        }
        /* 校验短信验证码 */
        SmsService smsService = new SmsServiceImpl();
        if (!smsService.verifySmsCode(instId, SmsTypeEnum.USER_REGISTER.getSmsType(), smsCode, authId)) {
            rglog.info("校验短信验证码失败");
            throw new BizException(RespCodeEnum.SMS_CODE_CHECK_ERROR.getRespCode(), RespCodeEnum.SMS_CODE_CHECK_ERROR.getRespDesc());
        }

        /* 初始化用户信息与商户绑定信息 并落库, 初始化部分response信息 */
        MchntBindInfo mchntBindInfo = initUserInfoAndMchntBindInfo(mchntBindRegisterRequest, mchntBindRegisterResponse);

        /* 获取用户绑定信息及对应角色权限 */
        MchntBindInfoBean facadeMchntBinInfo = new MchntBindInfoBean();
        BeanUtil.beanCopy(mchntBindInfo, facadeMchntBinInfo);
        List<MchntBindInfoBean> facadeMchntBindInfoBeanList = new ArrayList<>();
        BspsMchntBaseInfoMapper bspsMchntBaseInfoMapper = new BspsMchntBaseInfoMapperImpl();
        MchntBaseInfo mchntBaseInfo = bspsMchntBaseInfoMapper.selectBspsMchntBaseInfoByPrimaryKey(instId, mchntBindInfo.getMchntNo());
        if (null != mchntBaseInfo) {
            facadeMchntBinInfo.setMchntName(mchntBaseInfo.getMchntName());
            facadeMchntBinInfo.setCashWithdrawalFlag(mchntBaseInfo.getCashWithdrawalFlag());
        }
        facadeMchntBinInfo.setMchntType(mchntBindInfo.getBindMchntType());
        BspsUserRoleInfoMapper bspsUserRoleInfoMapper = new BspsUserRoleInfoMapperImpl();
        List<UserRoleInfo> userRoleInfoList = bspsUserRoleInfoMapper.selectBspsUserRoleInfoToChannelMenu(instId, BspsUserRoleTypeEnum.MCHNT_ARTIF.getRoleType(), chanlId);
        if (!CollectionUtils.isEmpty(userRoleInfoList)) {
            List<PrivilegeInfoBean> privilegeInfoBeanList = userRoleInfoList.stream().map(this::convertPrivilegeInfo).collect(Collectors.toList());
            facadeMchntBinInfo.setPrivilegeInfoBeanList(privilegeInfoBeanList);
        }
        facadeMchntBindInfoBeanList.add(facadeMchntBinInfo);
        mchntBindRegisterResponse.setMchntBindInfoBeanList(facadeMchntBindInfoBeanList);

        Header header = mchntBindRegisterRequest.getHeader();
        UserSessionInfo keySessionInfo = JSON.parseObject(RedisUtil.onceGet(header.getSession()), UserSessionInfo.class);
        if (null != keySessionInfo) {
            keySessionInfo.setUserId(mchntBindInfo.getBindUserId());
            RedisUtil.onceSet(header.getSession(), JSONObject.toJSONString(keySessionInfo), BspsAppParamConstant.SESSION_EFFECTIVE_TIME);
            //生成新的会话id
            String newSessionId = RandomUtil.getUUID();
            UserSessionInfo userSessionInfo = new UserSessionInfo();
            userSessionInfo.setUserId(mchntBindInfo.getBindUserId());
            userSessionInfo.setSignatureKey(keySessionInfo.getSignatureKey());
            userSessionInfo.setSensitiveKey(keySessionInfo.getSensitiveKey());
            RedisUtil.onceSet(newSessionId, JSONObject.toJSONString(userSessionInfo), BspsAppParamConstant.SESSION_EFFECTIVE_TIME);
            header.setSession(newSessionId);
            mchntBindRegisterResponse.setHeader(header);
        } else {
            rglog.info("获取session失败！");
        }

        //法人认证注册公众号消息推送
        if ("WECHAT".equals(chanlId)) {
            XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
            MchntAuthMsgPushRequest mchntAuthMsgPushRequest = new MchntAuthMsgPushRequest();
            cc.rengu.igas.channel.wechat.facade.base.Header wxchatHeader = new cc.rengu.igas.channel.wechat.facade.base.Header();
            wxchatHeader.setInstId(instId);
            wxchatHeader.setVersion("1.0.0");
            wxchatHeader.setBizType("00");
            wxchatHeader.setTransDate(DateUtil.getCurrentDate());
            wxchatHeader.setTransTime(DateUtil.getCurrentTime());
            wxchatHeader.setSrcSysId(AppParamConstant.SYS_ID);
            wxchatHeader.setChanlId(ChannelEnum.BSPS.getChannelType());
            wxchatHeader.setTxnNum("mchntauth");
            wxchatHeader.setTraceNo(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
            mchntAuthMsgPushRequest.setHeader(wxchatHeader);
            mchntAuthMsgPushRequest.setChannelId(ChannelEnum.WXZF.getChannelType());
            mchntAuthMsgPushRequest.setAuthTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss"));
            mchntAuthMsgPushRequest.setTitleType("T00");
            mchntAuthMsgPushRequest.setOpenId(openId);
            if (null != mchntBaseInfo) {
                mchntAuthMsgPushRequest.setMchntName(mchntBaseInfo.getMchntName());
            }
            mchntAuthMsgPushRequest.setMchntNo(mchntNo);
            DubboService dubboService = new DubboServiceImpl();
            int dubboReturnCode = dubboService.asynCallDubboService("wechatMsgPushService", "mchntAuthMsgPush", mchntAuthMsgPushRequest, null);
            if (0 != dubboReturnCode) {
                rglog.error("法人认证公众号消息推送失败！");
            }
        }
        /* 拼装响应结果 */
        BizResponse<MchntBindRegisterResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(mchntBindRegisterResponse);
        return bizResponse;
    }

    /**
     * 初始化用户信息和商户信息
     *
     * @param mchntBindRegisterRequest  商户注册请求信息
     * @param mchntBindRegisterResponse 商户注册响应信息
     *                                  return MchntBindInfo 商户绑定信息
     */
    private MchntBindInfo initUserInfoAndMchntBindInfo(MchntBindRegisterRequest mchntBindRegisterRequest, MchntBindRegisterResponse mchntBindRegisterResponse) throws Exception {
        UserInfo userInfo = new UserInfo();
        MchntBindInfo mchntBindInfo = new MchntBindInfo();
        String instId = mchntBindRegisterRequest.getHeader().getInstId();
        String channelId = mchntBindRegisterRequest.getHeader().getChanlId();
        String mchntNo = mchntBindRegisterRequest.getMchntNo();
        String mchntType = mchntBindRegisterRequest.getMchntType();
        String nickName = mchntBindRegisterRequest.getNickName();
        String loginPassword = mchntBindRegisterRequest.getPassword();
        String confirmPassword = mchntBindRegisterRequest.getConfirmPassword();
        String loginId = mchntBindRegisterRequest.getUserId();
        String roleType;
        if (BspsMchntTypeEnum.AGENT_MCHNT.getMchntType().equals(mchntType)) {
            roleType = BspsUserRoleTypeEnum.AGENT_MANAGER.getRoleType();
        } else if (BspsMchntTypeEnum.PLAT_MCHNT.getMchntType().equals(mchntType)) {
            roleType = BspsUserRoleTypeEnum.PLATFORM_MANAGER.getRoleType();
        } else if (BspsMchntTypeEnum.GROUP_MCHNT.getMchntType().equals(mchntType)) {
            roleType = BspsUserRoleTypeEnum.GROUP_MANAGER.getRoleType();
        } else {
            BspsMchntBaseInfoMapper bspsMchntBaseInfoMapper = new BspsMchntBaseInfoMapperImpl();
            MchntBaseInfo mchntBaseInfo = bspsMchntBaseInfoMapper.selectBspsMchntBaseInfoByPrimaryKey(instId, mchntNo);
            if (null != mchntBaseInfo && MchntStatusEnum.NORMAL.getStatus().equals(mchntBaseInfo.getMchntStatus())) {
                mchntType = mchntBaseInfo.getMchntType();
            } else {
                rglog.error("商户状态异常");
                throw new BizException(RespCodeEnum.MCHNT_STATUS_ABNORMAL.getRespCode(), RespCodeEnum.MCHNT_STATUS_ABNORMAL.getRespDesc());
            }
            if (BspsMchntTypeEnum.CHAIN_MCHNT_STORE.getMchntType().equals(mchntType)) {
                roleType = BspsUserRoleTypeEnum.MCHNT_MANAGER.getRoleType();
            } else {
                roleType = BspsUserRoleTypeEnum.MCHNT_ARTIF.getRoleType();
            }
        }
        //默认false,商户未注册绑定
        boolean upFlag = false;
        // 查询商户是否有绑定法人
        BspsMchntBindInfoMapper bspsMchntBindInfoMapper = new BspsMchntBindInfoMapperImpl();
        List<MchntBindInfo> mchntBindInfosList = bspsMchntBindInfoMapper.selectBspsMchntBindInfoByMchntNoAndRoleType(instId, mchntNo, roleType);
        if (!CollectionUtils.isEmpty(mchntBindInfosList)) {
            // 更新操作
            rglog.info("商户已存在用户");
            if (BspsMchntTypeEnum.AGENT_MCHNT.getMchntType().equals(mchntType) || BspsMchntTypeEnum.PLAT_MCHNT.getMchntType().equals(mchntType)
                    || BspsMchntTypeEnum.GROUP_MCHNT.getMchntType().equals(mchntType)) {
                rglog.error("根据机构号：<{}>，商户号：<{}>，商户类型:<{}>,查询商户绑定关系，商户已注册!", instId, mchntNo, mchntType);
                throw new BizException(RespCodeEnum.MCHNT_ALREADY_REGISTER.getRespCode(), RespCodeEnum.MCHNT_ALREADY_REGISTER.getRespDesc());
            }
            if (mchntBindInfosList.size() > 1) {
                rglog.error("根据机构号：<{}>，商户号：<{}>查询商户绑定关系，存在多条商户法人信息!", instId, mchntNo);
                throw new BizException(RespCodeEnum.MCHNT_ALREADY_REGISTER.getRespCode(), RespCodeEnum.MCHNT_ALREADY_REGISTER.getRespDesc());
            }
            //此时绑定数据应该有且仅有一条
            upFlag = true;
            mchntBindInfo = mchntBindInfosList.get(0);
            BspsUserInfoMapper bspsUserInfoMapper = new BspsUserInfoMapperImpl();
            userInfo = bspsUserInfoMapper.selectBspsUserInfoByUserId(instId, mchntBindInfo.getBindUserId());
            if (null == userInfo) {
                rglog.error("用户信息查询失败");
                throw new BizException(RespCodeEnum.MCHNT_ALREADY_REGISTER.getRespCode(), "商户已注册法人账户,商户法人账户信息查询失败");
            }
            String userLoginId = userInfo.getUserLoginId();
            String userOpenId = userInfo.getOpenId();
            if ((StringUtil.isEmptyOrNull(userLoginId) || "LOGINID".equals(userLoginId)) && (StringUtil.isEmptyOrNull(userOpenId) || "OPENID".equals(userOpenId))) {
                rglog.error("根据机构号：<{}>，商户号：<{}>查询商户绑定关系，存在商户法人信息!", instId, mchntNo);
                throw new BizException(RespCodeEnum.MCHNT_ALREADY_REGISTER.getRespCode(), "商户已注册法人账户,商户法人账户异常");
            }
            if ("WECHAT".equals(channelId)) {
                rglog.error("商户已注册用户");
                throw new BizException(RespCodeEnum.MCHNT_ALREADY_REGISTER.getRespCode(), RespCodeEnum.MCHNT_ALREADY_REGISTER.getRespDesc());
            } else if ("PCWEB".equals(channelId)) {
                if (!StringUtil.isEmptyOrNull(userLoginId) && !"LOGINID".equals(userLoginId)) {
                    rglog.error("商户法人微信渠道已注册");
                    throw new BizException(RespCodeEnum.MCHNT_ALREADY_REGISTER.getRespCode(), RespCodeEnum.MCHNT_ALREADY_REGISTER.getRespDesc());
                }
                SafeKeyBoardService safeKeyBoardService = new SafeKeyBoardServiceImpl();
                Header header = mchntBindRegisterRequest.getHeader();
                UserSessionInfo keySessionInfo = JSON.parseObject(RedisUtil.onceGet(header.getSession()), UserSessionInfo.class);
                if (null == keySessionInfo) {
                    rglog.error("session超时");
                    throw new BizException(RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespCode(), RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespDesc());
                }
                String randomString = keySessionInfo.getRandomString();
                keySessionInfo.setRandomString("");
                RedisUtil.onceSet(header.getSession(), JSONObject.toJSONString(keySessionInfo), BspsAppParamConstant.SESSION_EFFECTIVE_TIME);

                PasswordInfo passwordInfo = new PasswordInfo(mchntBindRegisterRequest.getMchntNo(), PinTypeEnum.MIXED, loginPassword);
                loginPassword = safeKeyBoardService.encryptPassword(instId, null, passwordInfo, null);
                userInfo.setLoginPassword(loginPassword);
            } else {
                rglog.error("渠道标识错误！channelId:<{}>", channelId);
                throw new BizException(RespCodeEnum.MCHNT_ALREADY_REGISTER.getRespCode(), "渠道无操作权限");
            }
        } else {
            rglog.error("商户类型mchntType：" + mchntType);
            if (!"PCWEB".equals(channelId) && (BspsMchntTypeEnum.GROUP_MCHNT.getMchntType().equals(mchntType) || BspsMchntTypeEnum.PLAT_MCHNT.getMchntType().equals(mchntType)
                    || BspsMchntTypeEnum.AGENT_MCHNT.getMchntType().equals(mchntType))) {
                rglog.error("代理商只能在PC端进行注册");
                throw new BizException(RespCodeEnum.MCHNT_CHANNEL_REGISTER.getRespCode(), RespCodeEnum.MCHNT_CHANNEL_REGISTER.getRespDesc());
            }
            //新增操作
            if (BspsMchntTypeEnum.AGENT_MCHNT.getMchntType().equals(mchntType)) {
                BspsAgentInfoMapper bspsAgentInfoMapper = new BspsAgentInfoMapperImpl();
                AgentInfo agentInfo = bspsAgentInfoMapper.selectBspsAgentInfoByInstIdAndAgentCode(instId, mchntNo);
                if (null == agentInfo) {
                    rglog.error("根据机构号:<{}>，商户号：<{}>查询代理商商户信息失败!", instId, mchntNo);
                    throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
                }
                userInfo.setUserName(agentInfo.getArtifName());
                userInfo.setNickName(StringUtil.isEmptyOrNull(nickName) ? agentInfo.getArtifName() : nickName);
                userInfo.setEmail(agentInfo.getArtifEmail());
                userInfo.setMobileNo(agentInfo.getArtifMobile());
                mchntBindInfo.setBindMchntType(mchntType);
            } else if (BspsMchntTypeEnum.PLAT_MCHNT.getMchntType().equals(mchntType)) {
                BspsPlatformMchntInfoMapper bspsPlatformMchntInfoMapper = new BspsPlatformMchntInfoMapperImpl();
                PlatformMchntInfo platformMchntInfo = bspsPlatformMchntInfoMapper.selectBspsPlatformMchntInfoByInstIdAndMchntNo(instId, mchntNo);
                if (null == platformMchntInfo) {
                    rglog.error("根据机构号:<{}>，商户号：<{}>查询平台商商户信息失败!", instId, mchntNo);
                    throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
                }
                userInfo.setUserName(platformMchntInfo.getArtifName());
                userInfo.setNickName(StringUtil.isEmptyOrNull(nickName) ? platformMchntInfo.getArtifName() : nickName);
                userInfo.setEmail(platformMchntInfo.getArtifEmail());
                userInfo.setMobileNo(platformMchntInfo.getArtifMobile());
                mchntBindInfo.setBindMchntType(mchntType);
            } else if (BspsMchntTypeEnum.GROUP_MCHNT.getMchntType().equals(mchntType)) {
                MchntService mchntService = new MchntServiceImpl();
                GroupMchntInfo groupMchntInfo = mchntService.getGroupMchntInfo(instId, mchntNo);
                if (null == groupMchntInfo) {
                    rglog.error("根据机构号:<{}>，商户号：<{}>查询集团商户信息失败!", instId, mchntNo);
                    throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
                }
                userInfo.setUserName(groupMchntInfo.getArtifName());
                userInfo.setNickName(StringUtil.isEmptyOrNull(nickName) ? groupMchntInfo.getArtifName() : nickName);
                userInfo.setEmail(groupMchntInfo.getArtifEmail());
                userInfo.setMobileNo(groupMchntInfo.getArtifMobile());
                mchntBindInfo.setBindMchntType(mchntType);
            } else {
                BspsMchntSignInfoMapper bspsMchntSignInfoMapper = new BspsMchntSignInfoMapperImpl();
                MchntSignInfo mchntSignInfo = bspsMchntSignInfoMapper.selectBspsMchntSignInfoByPrimaryKey(instId, mchntNo);
                if (null == mchntSignInfo) {
                    rglog.error("根据机构号:<{}>，商户号：<{}>查询普通商户签约信息失败!", instId, mchntNo);
                    throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
                }
                userInfo.setUserName(mchntSignInfo.getArtifName());
                userInfo.setNickName(StringUtil.isEmptyOrNull(nickName) ? mchntSignInfo.getArtifName() : nickName);
                userInfo.setEmail(mchntSignInfo.getArtifEmail());
                userInfo.setMobileNo(mchntSignInfo.getArtifMobile());
                BspsMchntBaseInfoMapper mchntBaseInfoMapper = new BspsMchntBaseInfoMapperImpl();
                MchntBaseInfo mchntBaseInfo = mchntBaseInfoMapper.selectBspsMchntBaseInfoByPrimaryKey(instId, mchntNo);
                if (null == mchntBaseInfo) {
                    rglog.error("根据机构号:<{}>，商户号：<{}>查询普通商户基础信息失败!", instId, mchntNo);
                    throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
                }
                mchntBindInfo.setBindMchntType(mchntBaseInfo.getMchntType());
                mchntBindInfo.setChainMchntNo(mchntBaseInfo.getChainMchntNo());
            }

            userInfo.setInstId(instId);
            userInfo.setUserId(RandomUtil.getUUID());
            userInfo.setUserStatus(UserStatusEnum.NOMAL.getStatus());
            if (!StringUtil.isEmptyOrNull(mchntBindRegisterRequest.getOpenId()) && "WECHAT".equals(mchntBindRegisterRequest.getHeader().getChanlId())) {
                userInfo.setOpenId(mchntBindRegisterRequest.getOpenId());
            }
            if (!StringUtil.isEmptyOrNull(mchntBindRegisterRequest.getUserId()) && !StringUtil.isEmptyOrNull(loginPassword)) {
                userInfo.setUserLoginId(mchntBindRegisterRequest.getUserId());
                SafeKeyBoardService safeKeyBoardService = new SafeKeyBoardServiceImpl();
                if ("PCWEB".equals(channelId)) {
                    userInfo.setUserLoginId(loginId);
                    Header header = mchntBindRegisterRequest.getHeader();
                    UserSessionInfo keySessionInfo = JSON.parseObject(RedisUtil.onceGet(header.getSession()), UserSessionInfo.class);
                    if (null == keySessionInfo) {
                        rglog.error("session超时");
                        throw new BizException(RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespCode(), RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespDesc());
                    }
                    String randomString = keySessionInfo.getRandomString();
                    keySessionInfo.setRandomString("");
                    RedisUtil.onceSet(header.getSession(), JSONObject.toJSONString(keySessionInfo), BspsAppParamConstant.SESSION_EFFECTIVE_TIME);

                    String registerMchntNo = mchntBindRegisterRequest.getMchntNo();

                    registerMchntNo = registerMchntNo.replaceAll("AG", "").replaceAll("PM", "");

                    PasswordInfo passwordInfo = new PasswordInfo(registerMchntNo, PinTypeEnum.MIXED, loginPassword);
                    loginPassword = safeKeyBoardService.encryptPassword(instId, null, passwordInfo, null);
                } else {
                    PasswordInfo passwordInfo = new PasswordInfo(mchntBindRegisterRequest.getMchntNo(), PinTypeEnum.MIXED, loginPassword);
                    PasswordInfo confirmPasswordInfo = new PasswordInfo(mchntBindRegisterRequest.getMchntNo(), PinTypeEnum.MIXED, confirmPassword);
                    loginPassword = safeKeyBoardService.encryptPassword(instId, null, passwordInfo, null);
                    confirmPassword = safeKeyBoardService.encryptPassword(instId, null, confirmPasswordInfo, null);
                    if (!loginPassword.equals(confirmPassword)) {
                        rglog.error("用户上送的两次新密码不一致，不允许更新此密码，交易失败");
                        throw new BizException(RespCodeEnum.PASSWORD_INCONSISTENCY.getRespCode(), RespCodeEnum.PASSWORD_INCONSISTENCY.getRespDesc());
                    }
                }

                userInfo.setLoginPassword(loginPassword);
            }

            userInfo.setLoginAuthFlag("YYY");
            userInfo.setOprId("system");
            userInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));

            mchntBindInfo.setInstId(instId);
            mchntBindInfo.setMchntNo(mchntNo);
            mchntBindInfo.setBindUserId(userInfo.getUserId());
            mchntBindInfo.setBindNickName(userInfo.getNickName());

            mchntBindInfo.setBindUserRole(roleType);
            mchntBindInfo.setBindDate(DateUtil.getCurrentDate());
            mchntBindInfo.setBindTime(DateUtil.getCurrentTime());
            mchntBindInfo.setBindStatus(BindStatusEnum.BIND.getStatus());
            mchntBindInfo.setOprId("system");
            mchntBindInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        }

        registerUserInfoAndMchntBindInfo(userInfo, mchntBindInfo, mchntBindRegisterRequest, upFlag);

        //初始化 response
        mchntBindRegisterResponse.setNickName(userInfo.getNickName());
        if (!StringUtil.isEmptyOrNull(userInfo.getUserImagePath())) {
            mchntBindRegisterResponse.setUserImagePath(Base64.encodeBase64String(userInfo.getUserImagePath().getBytes()));
        }
        mchntBindRegisterResponse.setEmail(userInfo.getEmail());
        mchntBindRegisterResponse.setUserId(userInfo.getUserId());
        mchntBindRegisterResponse.setUserLoginId(userInfo.getUserLoginId());
        /*返回手机号*/
        rglog.debug("手机号为:<{}>", userInfo.getMobileNo());
        if (!StringUtil.isEmptyOrNull(userInfo.getMobileNo())) {
            mchntBindRegisterResponse.setPhoneNo(SensitiveDataUtil.desensitization("1", userInfo.getMobileNo()).split("\\|")[0]);
        }

        return mchntBindInfo;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        MchntBindRegisterResponse mchntBindRegisterResponse = (MchntBindRegisterResponse) bizResponse.getResult();
        ConvertUtil.convertInput(mchntBindRegisterResponse);
    }

    private PrivilegeInfoBean convertPrivilegeInfo(UserRoleInfo userRoleInfo) {
        PrivilegeInfoBean privilegeInfoBean = new PrivilegeInfoBean();
        BeanUtil.beanCopy(userRoleInfo, privilegeInfoBean);
        return privilegeInfoBean;
    }


    private void registerUserInfoAndMchntBindInfo(UserInfo userInfo, MchntBindInfo mchntBindInfo, MchntBindRegisterRequest registerRequest, boolean upFlag) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();

        UserLoginInfo userLoginInfo = new UserLoginInfo();
        BspsUserLoginInfoMapper bspsUserLoginInfoMapper = new BspsUserLoginInfoMapperImpl();
        userLoginInfo.setInstId(userInfo.getInstId());
        userLoginInfo.setLoginType(registerRequest.getHeader().getChanlId());
        userLoginInfo.setUserId(userInfo.getUserId());
        userLoginInfo.setLoginTime(DateUtil.getCurrentDateTime(BspsAppParamConstant.yyyy_MM_dd_HHmmssSSS));
        userLoginInfo.setSessionId(registerRequest.getHeader().getSession());
        userLoginInfo.setLastOprTime(DateUtil.getCurrentDateTime(BspsAppParamConstant.yyyy_MM_dd_HHmmssSSS));
        userLoginInfo.setLoginStatus("0");   //0-登录  1-登出

        userLoginInfo.setLoginIp(registerRequest.getDevRiskInfo().getDevIp());
        userLoginInfo.setDevModel(registerRequest.getDevRiskInfo().getDevModel());
        userLoginInfo.setDevSn(registerRequest.getDevRiskInfo().getDevSerialNo());
        userLoginInfo.setDevUnqId(registerRequest.getDevRiskInfo().getDevUniqueId());
        userLoginInfo.setDevMac(registerRequest.getDevRiskInfo().getDevMac());
        userLoginInfo.setLoginLongitude(registerRequest.getDevRiskInfo().getLongitude());
        userLoginInfo.setLoginLatitude(registerRequest.getDevRiskInfo().getLatitude());
        userLoginInfo.setAppVersion(registerRequest.getHeader().getVersion());
        /* 开启数据库事务 */
        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.OLTP_POOL_NAME);
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.OLTP_POOL_NAME);
        }

        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        dbsUtil.dbsBeginTransaction();
        int iReturnCode = bspsUserLoginInfoMapper.insertBspsUserLoginInfo(userLoginInfo);

        if (0 != iReturnCode) {
            dbsUtil.dbsEndTransaction(false);
            rglog.error("登记用户登录信息表失败,iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
        }

        BspsMchntBindInfoMapper bspsMchntBindInfoMapper = new BspsMchntBindInfoMapperImpl();
        BspsUserInfoMapper bspsUserInfoMapper = new BspsUserInfoMapperImpl();
        if (upFlag) {
            //更新
            if ("WECHAT".equals(registerRequest.getHeader().getChanlId())) {
                rglog.info("更新用户openId", userInfo.getOpenId(), registerRequest.getOpenId());
                iReturnCode = bspsUserInfoMapper.updateBspsOpenIdByPrimaryKey(userInfo, registerRequest.getOpenId());
            } else if ("PCWEB".equals(registerRequest.getHeader().getChanlId())) {
                rglog.info("更新用户登录密码和账户", userInfo.getUserLoginId(), registerRequest.getUserId(), userInfo.getLoginPassword(), registerRequest.getPassword());
                iReturnCode = bspsUserInfoMapper.updateBspsLoginIdLoginPasswordByUserId(registerRequest.getHeader().getInstId(), registerRequest.getUserId(), userInfo.getLoginPassword(), userInfo.getUserId());
            }
            if (0 != iReturnCode) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("更新用户信息表失败,iReturnCode:<{}>", iReturnCode);
                throw new BizException(RespCodeEnum.REGISTER_USER_INFO_ERROR.getRespCode(), RespCodeEnum.REGISTER_USER_INFO_ERROR.getRespDesc());
            }
            dbsUtil.dbsEndTransaction(true);
        } else {
            //新增
            iReturnCode = bspsUserInfoMapper.insertBspsUserInfo(userInfo);
            if (iReturnCode != 0) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("登记用户信息表失败,iReturnCode:<{}>", iReturnCode);
                throw new BizException(RespCodeEnum.REGISTER_USER_INFO_ERROR.getRespCode(), RespCodeEnum.REGISTER_USER_INFO_ERROR.getRespDesc());
            }
            iReturnCode = bspsMchntBindInfoMapper.insertBspsMchntBindInfo(mchntBindInfo);
            if (iReturnCode != 0) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("登记商户绑定关系表失败,iReturnCode:<{}>", iReturnCode);
                throw new BizException(RespCodeEnum.USER_BIND_MCHNT_ERROR.getRespCode(), RespCodeEnum.USER_BIND_MCHNT_ERROR.getRespDesc());
            }
            /* 拓展经理绑定商户二维码更为绑定人为法人ID */
            BspsQrCodeInfoMapper bspsQrCodeInfoMapper = new BspsQrCodeInfoMapperImpl();
            iReturnCode = bspsQrCodeInfoMapper.updateBspsQrCodeInfoBindUserByMchntNo(userInfo.getInstId(), mchntBindInfo.getMchntNo(), userInfo.getUserId());
            if (0 != iReturnCode && BspsAppParamConstant.NODATA_CODE != iReturnCode) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("更新二维码信息表失败,iReturnCode:<{}>", iReturnCode);
                throw new BizException(RespCodeEnum.BIND_QRCODE_ERROR.getRespCode(), RespCodeEnum.BIND_QRCODE_ERROR.getRespDesc());
            }
            dbsUtil.dbsEndTransaction(true);
        }
    }
}
